home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / MPW181-5 / _SETUP.1 / linux_obuffer.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-21  |  4.3 KB  |  186 lines

  1. /* linux_obuffer.cc
  2.  
  3.    Output buffer for Linux written by
  4.    Louis P. Kruger (lpkruger@phoenix.princeton.edu)
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. #ifdef LINUX
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <unistd.h>
  27. #include <fcntl.h>
  28. #include <sys/ioctl.h>
  29. #include <iostream.h>
  30.  
  31. extern "C" {
  32. #include <sys/soundcard.h>
  33. }
  34.  
  35. #include "args.h"
  36. #include "header.h"
  37. #include "obuffer.h"
  38.  
  39. int LinuxObuffer::audio_fd = -1;
  40.  
  41. int LinuxObuffer::open_audio_device (void)
  42. {
  43.   int fd;
  44.  
  45.   if ((fd = open ("/dev/dsp", O_WRONLY | O_NDELAY, 0)) < 0)
  46.     if (errno == EBUSY)
  47.     {
  48.       cerr << "Sorry, the audio device is busy!\n";
  49.       exit (1);
  50.     }
  51.     else
  52.     {
  53.       perror ("can't open /dev/dsp for writing");
  54.       exit (1);
  55.     }
  56.  
  57.   // turn NDELAY mode off:
  58.   int flags;
  59.   if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
  60.   {
  61.     perror ("fcntl F_GETFL on /dev/audio failed");
  62.     exit (1);
  63.   }
  64.   flags &= ~O_NDELAY;
  65.   if (fcntl (fd, F_SETFL, flags) < 0)
  66.   {
  67.     perror ("fcntl F_SETFL on /dev/audio failed");
  68.     exit (1);
  69.   }
  70.   return fd;
  71. }
  72.  
  73.  
  74. LinuxObuffer::LinuxObuffer (uint32 number_of_channels, MPEG_Args *maplay_args)
  75. {
  76. #ifdef DEBUG
  77.   if (!number_of_channels || number_of_channels > MAXCHANNELS)
  78.   {
  79.     cerr << "LinuxObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n";
  80.     exit (1);
  81.   }
  82. #endif
  83.   channels = number_of_channels;
  84.   for (int i = 0; i < number_of_channels; ++i)
  85.     bufferp[i] = buffer + i;
  86.  
  87.   if (audio_fd < 0)
  88.   {
  89.     cerr << "Internal error, LinuxObuffer::audio_fd has to be initialized\n"
  90.         "by LinuxObuffer::class_suitable()!\n";
  91.     exit (1);
  92.   }
  93.  
  94.   // configure the device:
  95.   int play_precision = 16;
  96.   int play_stereo = channels-1;
  97.   int play_sample_rate = maplay_args->MPEGheader->frequency ();
  98.  
  99.   if(
  100.       ioctl(audio_fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1 ||
  101.       ioctl(audio_fd, SNDCTL_DSP_STEREO, &play_stereo) == -1 ||
  102.       ioctl(audio_fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1
  103.     )
  104.   {
  105.     perror ("configuration of /dev/dsp failed");
  106.     exit (1);
  107.   }
  108. }
  109.  
  110.  
  111. LinuxObuffer::~LinuxObuffer (void)
  112. {
  113.   sleep (1);
  114.   close (audio_fd);
  115. }
  116.  
  117.  
  118. void LinuxObuffer::append (uint32 channel, int16 value)
  119. {
  120. #ifdef DEBUG
  121.   if (channel >= channels)
  122.   {
  123.     cerr << "illegal channelnumber in LinuxObuffer::append()!\n";
  124.     exit (1);
  125.   }
  126.   if (bufferp[channel] - buffer >= OBUFFERSIZE)
  127.   {
  128.     cerr << "buffer overflow!\n";
  129.     exit (1);
  130.   }
  131. #endif
  132.   *bufferp[channel] = value;
  133.   bufferp[channel] += channels;
  134. }
  135.  
  136. #ifdef SEEK_STOP
  137. void LinuxObuffer::clear_buffer(void)
  138. {
  139. }
  140.  
  141. void LinuxObuffer::set_stop_flag(void)
  142. {
  143. }
  144. #endif // SEEK_STOP
  145.  
  146. void LinuxObuffer::write_buffer (int)
  147. {
  148.   int length = (int)((char *)bufferp[0] - (char *)buffer);
  149.   if (write (audio_fd, buffer, length) != length)
  150.   {
  151.     perror ("write to /dev/dsp failed");
  152.     exit (1);
  153.   }
  154.   for (int i = 0; i < channels; ++i)
  155.     bufferp[i] = buffer + i;
  156. }
  157.  
  158.  
  159. BOOL LinuxObuffer::class_suitable (uint32 number_of_channels)
  160. {
  161.   // open the dsp audio device:
  162.   audio_fd = open_audio_device ();
  163.   return True;
  164. }
  165.  
  166. Obuffer *create_obuffer(MPEG_Args *maplay_args)
  167. {
  168.   Obuffer *buffer;
  169.  
  170.   enum e_mode mode = maplay_args->MPEGheader->mode();
  171.   enum e_channels which_channels = maplay_args->which_c;
  172.  
  173.   if (LinuxObuffer::class_suitable((mode == single_channel) ||
  174.                                                (which_channels != both)) ? 1 : 2)
  175.     if (mode == single_channel || which_channels != both)
  176.        buffer = new LinuxObuffer (1, maplay_args);
  177.     else
  178.        buffer = new LinuxObuffer (2, maplay_args);
  179.   else
  180.     return(NULL);
  181.  
  182.   return(buffer);
  183. }
  184.  
  185. #endif    /* LINUX */
  186.